package com.lee.study

import arrow.core.Either
import arrow.core.flatMap
import arrow.core.left
import arrow.core.right
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import java.math.BigDecimal


@Serializable
data class User(val id: Int, val points: Int)

fun calcBonus(user: User): Either<String, BigDecimal> =
    if (user.points < 0) "积分异常".left()
    else BigDecimal.valueOf(user.points * 0.15).right()

object Legacy {
    fun parseUser(json: String): User? {
        try {
            return Json.decodeFromString<User>(json)
        } catch (e: Exception) {
            return null
        }
    }
}

object Functional {
    fun parseUser(json: String): Either<String?, User> {
        try {
            return Json.decodeFromString<User>(json).right()
        } catch (e: Exception) {
            return Either.Left(e.message)
        }
    }

    fun userBonus(json: String): Either<String?, BigDecimal> {
        return parseUser(json).flatMap { calcBonus(it) }
    }
}

fun main() {
    val wrongJson = """{"id":1,"name":"Arrow","vip":true,"tags":["kotlin","json"]}"""
    val rightJson = """{"id":1,"points":100}"""
    println(Legacy.parseUser(wrongJson)?.points)
    println(Legacy.parseUser(rightJson)?.points)

    Functional.parseUser(wrongJson).fold({ println(it) }, { println(it.points) })
    Functional.parseUser(rightJson).fold({ println(it) }, { println(it.points) })

    Functional.userBonus(rightJson).fold({ println(it) }, { println(it) })

}